﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace EnterpriseServices.Service
{
    internal class ChannelManager<T>
    {

        /// <summary>
        /// Initializes a new instance of the <see cref="ChannelManager&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="endpointName">Name of the endpoint in the configuration.</param>
        internal ChannelManager(string endpointName)
        {
            _endpointName = endpointName;
            channel = new ChannelFactory<T>(_endpointName).CreateChannel();
            ((ICommunicationObject)channel).Faulted += new EventHandler(ChannelManager_Faulted);
        }

        /// <summary>
        /// sets up a proxy to be used by the .
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        internal T ChannelSetup(ChannelTask request)
        {
            // open the channel. in case it was closed before, the object got disposed. we need to create a new instance
            if (((ICommunicationObject)channel).State != CommunicationState.Opened && request == ChannelTask.Open)
            {
                if (((ICommunicationObject)channel).State == CommunicationState.Closed)
                {
                    channel = new ChannelFactory<T>(_endpointName).CreateChannel();
                }
                ((ICommunicationObject)channel).Open();
            }
            else if (request == ChannelTask.Close)
            {
                if (((ICommunicationObject)channel).State != CommunicationState.Closed)
                    ((ICommunicationObject)channel).Close();
            }

            return (T)channel;
        }

        /// <summary>
        /// Handles the Elapsed event of a timeout control.
        /// The method closes the underlying channel to release resources.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Timers.ElapsedEventArgs"/> instance containing the event data.</param>
        internal void timeout_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (((ICommunicationObject)channel).State != CommunicationState.Closed)
                ((ICommunicationObject)channel).Close();
        }

        /// <summary>
        /// Handles the Faulted event of the ChannelManager control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        void ChannelManager_Faulted(object sender, EventArgs e)
        {
            if (((ICommunicationObject)channel).State == CommunicationState.Faulted)
            {
                channel = new ChannelFactory<T>(_endpointName).CreateChannel();
                ((ICommunicationObject)channel).Faulted += new EventHandler(ChannelManager_Faulted);
            }
        }



        string _endpointName = string.Empty;

        T channel;
        public T Channel
        {
            set { channel = value; }
        }

    }

    internal enum ChannelTask
    {
        Open,
        Close
    }

}
